package common;



import com.hll.exception.DBException;
import com.hll.util.DBUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JDBCTemplate<T> {

    /**
     *模板的参数不确定，使用范式代替
     * 查询多条数据
     */
    public List<T> query(String sql, JDBCCallBack<T> jdbcCallBack) {

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        List<T> data = new ArrayList<T>();
        try {
            conn = DBUtil.getConnection();
            stmt = conn.prepareStatement(sql);
            jdbcCallBack.setParams(stmt);
            rs = stmt.executeQuery();

            while (rs.next()) {
                T Object = jdbcCallBack.rsToObject(rs);
                data.add(Object);
            }

        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.close(rs, stmt, conn);
        }

        return data;
    }

    /**
     * 这个里面的代码和上面query的类似，就直接调用query来实现这个方法
     * 这个查询一条数据
     */

    public T queryOne(String sql, JDBCCallBack<T> jdbcCallBack) {

        List<T> data = query(sql, jdbcCallBack);
        if (data != null && !data.isEmpty()) {
            return data.get(0);
        }
        return null;
    }

    /**
     * 更新数据的模板
     */
    public int update(String sql, JDBCCallBack<T> jdbcCallBack) {

        Connection conn = null;
        PreparedStatement stmt = null;
        int count = 0;

        try {
            conn = DBUtil.getConnection();
            stmt = conn.prepareStatement(sql);
            jdbcCallBack.setParams(stmt);
            count = stmt.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.close(null, stmt, conn);
        }
        return count;
    }

    /**
     * 增加数据的模板,
     * 需要主键
     */
    public int insert(String sql, JDBCCallBack<T> jdbcCallBack) {

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        int id = 0;

        try {
            conn = DBUtil.getConnection();
            /**得到生成的主键  Statment.RETURN_GENERATED_KEYS*/
            stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            jdbcCallBack.setParams(stmt);

            stmt.executeUpdate();

            rs = stmt.getGeneratedKeys();
            if (rs.next()) {
                id = rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.close(rs, stmt, conn);
        }
        return id;
    }


    /**
     * 增加数据的模板,
     * 不需要主键
     */
    public void insertWithoutKey(String sql, JDBCCallBack<T> jdbcCallBack) {

        Connection conn = null;
        PreparedStatement stmt = null;

        try {
            conn = DBUtil.getConnection();
            stmt = conn.prepareStatement(sql);
            jdbcCallBack.setParams(stmt);

            stmt.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.close(null, stmt, conn);
        }
    }

    /**
     * 得到书籍数量的模板
     */
    public int getCount(String sql, JDBCCallBack<T> jdbcCallBack) {

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        int count = 0;
        try {
            conn = DBUtil.getConnection();
            stmt = conn.prepareStatement(sql);
            rs = stmt.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.close(rs, stmt, conn);
        }
        return count;
    }
}
